#include "diagramscene.h"
#include <QMimeData>
#include <QDebug>
#include <QTextCursor>
#include <QIcon>
#include "relation.h"
#include "stepbase.h"
#include <QScopedPointer>
#include "image.h"
#include <QtMath>

static bool compareBarData(const void *barAmount1, const void *barAmount2)
{
    StepBase* aa=(StepBase *)barAmount1;
    StepBase* bb=(StepBase *)barAmount2;
    return aa->scenePos().rx() < aa->scenePos().rx();
}

DiagramScene::DiagramScene(QObject *parent) : QGraphicsScene(parent)
{
    setSceneRect(-300,-300,600,600);
    initForm();
}

void DiagramScene::resetScene()
{
    for(auto item: items())
    {
        if(item->type() != Relation::Type)
        {
            removeItem(item);
            delete item;
            item = nullptr;
        }
    }
    //添加变量组件和响应组件
    initStep();
}

bool DiagramScene::findType(int type)
{
    for(auto item: items())
    {
        if(item->type() == type)
        {
            return true;
        }
    }
    return false;
}

void DiagramScene::collidingandRelation(StepBase* _step)
{
    if(_step == nullptr)
    {
        return;
    }
    if(_step->collidesWithItem(relation[0]))
    {
        QPointF p = _step->scenePos();
        p.setY(relation[0]->line().p1().ry());
        _step->setPos(p);
        _step->setDirection(Relation::RIGHT);


    }
    else if(_step->collidesWithItem(relation[1]))
    {
        QPointF p = _step->scenePos();
        p.setX(relation[1]->line().p1().rx());
        _step->setPos(p);
        _step->setDirection(Relation::DOWN);
    }
    else if(_step->collidesWithItem(relation[2]))
    {
        QPointF p = _step->scenePos();
        p.setY(relation[2]->line().p1().ry());
        _step->setPos(p);
        _step->setDirection(Relation::LEFT);
    }
    else if(_step->collidesWithItem(relation[3]))
    {
        QPointF p = _step->scenePos();
        p.setX(relation[3]->line().p1().rx());
        _step->setPos(p);
        _step->setDirection(Relation::UP);
    }
    else
    {
        _step->setDirection(Relation::NODIRECTION);
    }

}

void DiagramScene::ComponentOrdering( QList<StepBase*> &list)
{
    QList<StepBase*> stepList1;
    QList<StepBase*> stepList2;
    QList<StepBase*> stepList3;
    QList<StepBase*> stepList4;
    for(auto _step:items())
    {
        StepBase* step = dynamic_cast<StepBase*>(_step);
        if(step!=Q_NULLPTR)
        {
            qDebug()<<step->direction();
            if(step->direction() == Relation::RIGHT)
            {
                stepList1.push_back(step);

            }
            else  if(step->direction() == Relation::DOWN)
            {
                stepList2.push_back(step);

            }
            else  if(step->direction() == Relation::LEFT)
            {
                stepList3.push_back(step);

            }
            else  if(step->direction() == Relation::UP)
            {
                stepList4.push_back(step);

            }
        }

    }
    if(!stepList1.isEmpty())
    {

        //qsort(stepList1.begin(),stepList1.end(),compareBarData);
        qSort(stepList1.begin(), stepList1.end(),[](const StepBase* a, const StepBase* b) -> bool { return a->scenePos().x() < b->scenePos().x(); });
        for(auto _step:stepList1)
        {
            list.push_back(_step);
        }
    }
    if(!stepList2.isEmpty())
    {
        qSort(stepList2.begin(), stepList2.end(),[](const StepBase* a, const StepBase* b) -> bool { return a->scenePos().y() < b->scenePos().y(); });
        for(auto _step:stepList2)
        {
            list.push_back(_step);
        }
    }
    if(!stepList3.isEmpty())
    {
        qSort(stepList3.begin(), stepList3.end(),[](const StepBase* a, const StepBase* b) -> bool { return a->scenePos().x() > b->scenePos().x(); });
        for(auto _step:stepList3)
        {
            list.push_back(_step);
        }
    }
    if(!stepList4.isEmpty())
    {
        qSort(stepList4.begin(), stepList4.end(),[](const StepBase* a, const StepBase* b) -> bool { return a->scenePos().y() > b->scenePos().y(); });
        for(auto _step:stepList4)
        {
            list.push_back(_step);
        }
    }
}


void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
//    qDebug()<<mouseEvent->scenePos();
    QGraphicsScene::mousePressEvent(mouseEvent);
}


void DiagramScene::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
    if (event->mimeData()->hasFormat(myMimeType()))
        event->accept();
    else
        event->ignore();
}

void DiagramScene::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
{
    event->accept();
}

void DiagramScene::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
{
        event->setDropAction(Qt::MoveAction);
        event->accept();
}

void DiagramScene::dropEvent(QGraphicsSceneDragDropEvent *event)
{
    StepData data;

    QByteArray itemData = event->mimeData()->data(myMimeType());
    QDataStream dataStream(&itemData, QIODevice::ReadOnly);

    dataStream >> data.m_text >> data.m_pix >> data.m_stepType;

    if(findType(data.m_stepType) == false)
    {
        StepBase* step = createStep(data);
        step->setPos(event->scenePos());
        addItem(step);
        collidingandRelation(step);
    }
    event->setDropAction(Qt::MoveAction);
    event->accept();
}

void DiagramScene::slotsDoubleClickedItem()
{
    QObject* obj = sender();
    StepBase* step = qobject_cast<StepBase*>(obj);
    if(step!=nullptr)
    {
        emit doubleClickedItem(step);
    }
}

StepBase* DiagramScene::createStep(const StepData &_data)
{
    StepBase* step = new StepBase;
    step->setData(_data);
    connect(step,&StepBase::doubleClicked,this,&DiagramScene::slotsDoubleClickedItem);
    return step;
}

void DiagramScene::initForm()
{
    resetScene();
    //添加线条
    createRelation();
    //添加变量组件和响应组件
    initStep();

}

void DiagramScene::createRelation()
{
    relation[0] = new Relation;
    relation[0]->setLine(-250,-250,250,-250);
    relation[0]->setZValue(-1000);
    relation[0]->addArrow(Relation::RIGHT);


    relation[1] = new Relation;
    relation[1]->setLine(250,-250,250,250);
    relation[1]->setZValue(-1000);
    relation[1]->addArrow(Relation::DOWN);


    relation[2] = new Relation;
    relation[2]->setLine(250,250,-250,250);
    relation[2]->setZValue(-1000);
    relation[2]->addArrow(Relation::LEFT);


    relation[3] = new Relation;
    relation[3]->setLine(-250,250,-250,-250);
    relation[3]->setZValue(-1000);
    relation[3]->addArrow(Relation::UP);
    addItem(relation[0]);
    addItem(relation[1]);
    addItem(relation[2]);
    addItem(relation[3]);
}

void DiagramScene::initStep()
{
    if(relation[0] != nullptr)
    {
        QPointF p1 = relation[0]->line().p1();
        QPointF p2 = relation[0]->line().p2();
        QPointF pPassage = (p2-p1)/3;
        StepData dataExchange(QPixmap(EXCHANGE_IMAGE).scaled(60,60),"变量",StepData::EXCHANGE);
        StepBase* stepExchange = createStep(dataExchange);
        stepExchange->setPos(p1+pPassage);
        stepExchange->setDirection(Relation::RIGHT);
        addItem(stepExchange);


        StepData dataStructure(QPixmap(STRUCTURE_IMAGE).scaled(60,60),"响应",StepData::STRUCTURE);
        StepBase* stepStructure = createStep(dataStructure);
        stepStructure->setPos(p2-pPassage);
        stepStructure->setDirection(Relation::RIGHT);
        addItem(stepStructure);
    }


}



